package edu.uestc.gene.scripts;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ThresholdDetector implements Serializable {

	/**
	 * 
	 */
	public static final long serialVersionUID = 1L;

	public static final String DGFILENAME = "./drug_gene.txt";
	public static final String DAFILENAME = "./drug_ADR.txt";
	public static final String BADDFILENAME = "./gene2ADR.badd";

	/**
	 * 读入的是DG表的标志
	 */
	public final static int FLAG_D_G = 0;
	/**
	 * 读入的是DA表的标志
	 */
	public final static int FLAG_D_A = 1;

	public int DRUG_NUM;// 药品种类
	public int GENE_NUM;// 基因种类
	public int EFFECT_NUM;// 副作用种类

	public String[][] data;// 全局数据表

	/**
	 * 将各个变量用简单整型变量代替<br>
	 * 比如药物ASAH1,CYP3A4,HCN4,KCNH2,NR0B2<br>
	 * 分别映射成ASAH1-1,CYP3A4-2,HCN4-3,KCNH2-4,NR0B2-5 以节省内存使用量
	 **/
	public Map<String, Integer> drugMapping;
	public Map<String, Integer> geneMapping;
	public Map<String, Integer> effectMapping;

	public Map<String, String> effectNameMapping;

	public List<String> genes, effects, drugs;// 三种变量总出现。
	public List<String> _genes, _effects, _drugs;// 三种变量的种类,每种变量的每个数据只出现一次

	// 按行读取的数据
	public List<String> all1, all2;// all1是DG表，all2是DA表

	public Set<String> effectCount;// 多基因查询时记录副作用种类数量

	/**
	 * 类似如下的表格，不算表头
	 * <table border="1" cellspacing="0" align="center" cellpadding="0" bordercolor=#000000>
	 * <tr>
	 * <td></td>
	 * <td>a1</td>
	 * <td>a2</td>
	 * <td>a3</td>
	 * <td>a4</td>
	 * </tr>
	 * <tr>
	 * <td>g1</td>
	 * <td></td>
	 * <td>d3</td>
	 * <td></td>
	 * <td>d3</td>
	 * </tr>
	 * <tr>
	 * <td>g2</td>
	 * <td>d1</td>
	 * <td></td>
	 * <td>d3</td>
	 * <td></td>
	 * </tr>
	 * <tr>
	 * <td>g3</td>
	 * <td></td>
	 * <td>d3</td>
	 * <td>d2</td>
	 * <td>d3</td>
	 * </tr>
	 * <tr>
	 * <td>g4</td>
	 * <td>d1</td>
	 * <td>d3</td>
	 * <td>d1</td>
	 * <td>d3</td>
	 * </tr>
	 * </table>
	 */
	public String[][] multiGeneMap = null;// 多基因副作用的药物表

	public void mapping(List<String> list, Map<String, Integer> map) {
		int len = list.size();
		for (int i = 0; i < len; i++) {
			map.put(list.get(i).trim(), i);
		}
	}

	public List<String> dataInput(String fileName, int flag) {
		List<String> list = getAllInfoByLine(fileName);
		if (flag == FLAG_D_G) {
			all1 = list;
		}
		if (flag == FLAG_D_A) {
			all2 = list;
		}
		return list;
	}

	public Map<String, String> getEffectNameMapping() {
		Map<String, String> result = new HashMap<String, String>();
		List<String> content = getAllInfoByLine("./3_ID.txt");
		if (content == null) {
			return null;
		}
		for (String str : content) {
			String[] split = str.split(",");
			result.put(split[0], split[1]);
		}
		return result;
	}

	public void index() {
		genes = getAllKinds(all1);
		System.out.println("得到所有基因数据");
		effects = getAllKinds(all2);
		System.out.println("得到所有ADRs数据");
		drugs = getKindsOfDrugs(all1);
		System.out.println("得到所有药物数据");
		effectNameMapping = getEffectNameMapping();
		System.out.println("得到ADRs名字数据");
		// 将列表转一次集合来去重
		_genes = new ArrayList<String>(new HashSet<String>(genes));
		GENE_NUM = _genes.size();
		System.out.println("得到所有基因种类:" + GENE_NUM);
		_effects = new ArrayList<String>(new HashSet<String>(effects));
		EFFECT_NUM = _effects.size();
		System.out.println("得到所有ADRs种类:" + EFFECT_NUM);
		_drugs = new ArrayList<String>(new HashSet<String>(drugs));
		DRUG_NUM = _drugs.size();
		System.out.println("得到所有药物种类:" + DRUG_NUM);

		drugMapping = new HashMap<String, Integer>(DRUG_NUM);
		geneMapping = new HashMap<String, Integer>(GENE_NUM);
		effectMapping = new HashMap<String, Integer>(EFFECT_NUM);

		data = new String[EFFECT_NUM][GENE_NUM];
		for (int i = 0; i < data.length; i++) {
			for (int j = 0; j < data[0].length; j++) {
				data[i][j] = "";
			}
		}

		mapping(_drugs, drugMapping);
		System.out.println("药物集合映射结束");

		mapping(_effects, effectMapping);
		System.out.println("ADRs集合映射结束");

		mapping(_genes, geneMapping);
		System.out.println("基因集合映射结束");

		createDataTable();
	}

	public void createDataTable() {
		int len = all1.size();
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		for (int i = 0; i < len; i++) {
			String dg = all1.get(i);
			String da = all2.get(i);
			String[] tmp1 = dg.split(",");
			tmp1[0] = drugMapping.get(tmp1[0]).toString();
			if (!tmp1[1].trim().equals(""))
				for (int j = 1; j < tmp1.length; j++) {
					tmp1[j] = geneMapping.get(tmp1[j].trim()).toString();
				}
			for (int j = 0; j < tmp1.length; j++) {
				sb1.append(tmp1[j] + ",");
			}
			sb1.append("\n");
			String[] tmp2 = da.split(",");
			tmp2[0] = drugMapping.get(tmp2[0]).toString();
			if (tmp2.length > 1)
				if (!tmp2[1].trim().equals(""))
					for (int j = 1; j < tmp2.length; j++) {
						tmp2[j] = effectMapping.get(tmp2[j].trim()).toString();
					}
			for (int j = 0; j < tmp2.length; j++) {
				sb2.append(tmp2[j] + ",");
			}
			sb2.append("\n");
			for (int k = 1; k < tmp2.length; k++)
				for (int j = 1; j < tmp1.length; j++) {
					if (tmp2[k].trim().equals("")) {
						continue;
					}
					int m = Integer.valueOf(tmp2[k]);
					int n = Integer.valueOf(tmp1[j]);
					data[m][n] += tmp1[0] + ",";
				}
		}
	}

	/**
	 * 检查指定基因是否存在
	 * 
	 * @param gene
	 * @return
	 */
	public boolean checkGene(String gene) {
		boolean isExist = true;
		try {
			int i = geneMapping.get(gene);
		} catch (NullPointerException e) {
			isExist = false;
		}
		return isExist;
	}

	public List<String> getAllKinds(List<String> all) {
		List<String> list = new ArrayList<String>();
		int len = all.size();
		for (int i = 0; i < len; i++) {
			String tmp = all.get(i);
			String[] gs = tmp.substring(tmp.indexOf(",") + 1).split(",");
			for (String s : gs) {
				if (!s.trim().equals("")) {
					list.add(s.trim());
				}
			}
		}
		return list;
	}

	public List<String> getKindsOfDrugs(List<String> all) {
		List<String> drugs = new ArrayList<String>();
		int len = all.size();
		for (int i = 0; i < len; i++) {
			String tmp = all.get(i);
			drugs.add(tmp.substring(0, tmp.indexOf(",")).trim());
		}
		return drugs;
	}

	/**
	 * 根据输入的gene对全局数据表做统计返回结果
	 * 
	 * @param gene
	 * @return key是副作用序号，value是药物序列号集，以逗号分割
	 */
	public Map<String, String> dataHandle(String gene) {
		Map<Integer, String> result = new HashMap<Integer, String>();
		int index = -1;
		index = geneMapping.get(gene);
		for (int i = 0; i < data.length; i++) {
			String drug = data[i][index];
			if (drug != null) {
				if (!drug.trim().equals(""))
					result.put(i, drug);
			}
		}
		return formatResult(result);
	}

	@SuppressWarnings("unchecked")
	public Map<String, String>[] dataHandle(String[] genes) {
		effectCount = new HashSet<String>();
		Map[] results = new Map[genes.length];
		for (int i = 0; i < genes.length; i++) {
			results[i] = dataHandle(genes[i]);
			effectCount.addAll(results[i].keySet());
		}
		multiGeneMap = new String[genes.length][effectMapping.size()];
		int i = 0;// 多基因药物表的基因列表序号,上面二维数组的x
		for (Map result : results) {
			Iterator it = result.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry entry = (Map.Entry) it.next();
				multiGeneMap[i][effectMapping.get(entry.getKey())] = entry
						.getValue().toString();
			}
			i++;
		}
		return results;
	}

	public Map<String, String> getResultData() {
		Map<String, String> resultData = new HashMap<String, String>();
		for (String str : effectMapping.keySet()) {
			int index = effectMapping.get(str);
			for (int i = 0; i < multiGeneMap.length; i++) {
				if (multiGeneMap[i][index] != null) {
					if (resultData.containsKey(str) && !str.equals("")) {
						String value = resultData.get(str);
						resultData.put(str, multiGeneMap[i][index] + ","
								+ value);
					} else {
						resultData.put(str, multiGeneMap[i][index]);
					}
				}
			}
		}
		return resultData;
	}

	public String[] multiGeneResultStatistics(String[] genes,
			Map<String, String>[] result) {
		String[][] probMatrix = multiGeneMap.clone();
		for (int i = 0; i < genes.length; i++) {
			int count = 0;
			for (int j = 0; j < probMatrix[i].length; j++) {
				if (probMatrix[i][j] != null)
					count += multiCount(probMatrix[i][j].split(","));
			}
			for (int j = 0; j < probMatrix[i].length; j++) {
				if (probMatrix[i][j] != null)
					probMatrix[i][j] = roundDivisionString(
							multiCount(probMatrix[i][j].split(",")), count, 4);
			}
		}
		String[] finalProbability = new String[probMatrix[0].length];
		for (int i = 0; i < probMatrix[0].length; i++) {
			StringBuffer probs = new StringBuffer();
			for (int j = 0; j < genes.length; j++) {
				probs.append(probMatrix[j][i] + ",");
			}
			finalProbability[i] = roundAtLeastTimesString(probs.toString()
					.split(","), 4);
		}

		// String[] finalProbability = new String[probMatrix[0].length];
		// int row = multiGeneMap[0].length, column = multiGeneMap.length;
		// String[][] multiProb = new String[column][row];
		// for (int i = 0; i < column; i++) {
		// int size = count(result[i]);
		// for (int j = 0; j < row; j++) {
		// if (multiGeneMap[i][j] != null) {
		// multiProb[i][j] = roundDivisionString(
		// multiGeneMap[i][j].split(",").length, size, 4);
		// }
		// }
		// }
		// List temp;
		// int index = 0;
		// for (int i = 0; i < row; i++) {
		// temp = new ArrayList();
		// for (int j = 0; j < column; j++) {
		// if (multiProb[j][i] != null) {
		// temp.add(multiProb[j][i]);
		// }
		// }
		// if (temp.size() != 0)
		// finalProbability[index++] = roundAtLeastTimesString(
		// convert(temp.toArray()), 4);
		// }
		return finalProbability;
	}

	/**
	 * 根据输入的gene对全局数据表做统计返回结果
	 * 
	 * @param gene1
	 * @param gene2
	 * @return key是副作用序号，value是药物序列号集，以逗号分割
	 */
	public Map<String, String> dataHandle(String gene1, String gene2) {
		Map<Integer, String> result = new HashMap<Integer, String>();
		int index1 = -1, index2 = -1;
		index1 = geneMapping.get(gene1);
		index2 = geneMapping.get(gene2);
		for (int i = 0; i < data.length; i++) {
			Set<String> set = new HashSet<String>();
			String drug[] = (data[i][index1] + data[i][index2]).split(",");
			for (String d : drug) {
				if (d.trim().equals(""))
					continue;
				set.add(d);
			}
			StringBuffer sb = new StringBuffer();
			Iterator<String> iterator = set.iterator();
			while (iterator.hasNext()) {
				sb.append(iterator.next() + ",");
			}
			String d = sb.toString();
			if (d != null) {
				if (!d.trim().equals(""))
					result.put(i, d);
			}
		}
		return formatResult(result);
	}

	public Map<String, String> formatResult(Map<Integer, String> map) {
		Map<String, String> result = new HashMap<String, String>(map.size());
		Iterator iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry entry = (Map.Entry) iterator.next();
			String[] drugs = entry.getValue().toString().split(",");
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < drugs.length; i++) {
				sb.append(_drugs.get(Integer.valueOf(drugs[i])) + ",");
			}
			result.put(
					_effects.get(Integer.valueOf(entry.getKey().toString())),
					sb.toString());
		}
		return result;
	}

	public List<String> getAll1() {
		return all1;
	}

	public List<String> getAll2() {
		return all2;
	}

	public static int multiCount(String[] drugs) {
		int i = 0;
		for (String drug : drugs) {
			if (!isStringBlank(drug)) {
				i = i + 1;
			}
		}
		return i;
	}

	public static String[] convert(Object[] target) {
		String[] result = new String[target.length];
		for (int i = 0; i < target.length; i++) {
			result[i] = target[i].toString();
		}
		return result;
	}

	public static String roundAtLeastTimesString(String[] a, int scale) {
		BigDecimal one = new BigDecimal(1);
		if (a[0] == null || a[0].equals("null"))
			a[0] = 0 + "";
		BigDecimal tmp = one.subtract(new BigDecimal(a[0]));
		for (int i = 1; i < a.length; i++) {
			if (a[i] == null || a[i].equals("null"))
				a[i] = 0 + "";
			tmp = tmp.multiply(one.subtract(new BigDecimal(a[i]))).setScale(
					scale, 2);
		}
		return one.subtract(tmp).setScale(scale, 2).toString();
	}

	public static String roundDivisionString(int a, int b, int scale) {
		if (b == 0)
			return 0 + "";
		return new BigDecimal(a * 1.0 / b * 1.0).setScale(scale, 2).toString();
	}

	public static int count(Map<String, String> result) {
		Iterator it = result.entrySet().iterator();
		int i = 0;
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			i += multiCount(entry.getValue().toString().split(","));
		}
		return i;
	}

	public static boolean isStringBlank(String str) {
		return "".equals(str.replaceAll("\\s*", ""));
	}

	public static String[] getGenes(String str) {
		List<String> gene = new ArrayList<String>();
		String[] genes = null;
		for (String s : str.split(",")) {
			if (!isStringBlank(s)) {
				gene.add(s);
			}
		}
		genes = new String[gene.size()];
		for (int i = 0; i < genes.length; i++) {
			genes[i] = gene.get(i);
		}
		return genes;
	}

	public static List<String> getAllInfoByLine(String fileName) {
		List<String> list = new ArrayList<String>();
		File file = new File(fileName);
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String tempString = null;
			int line = 1;
			while ((tempString = reader.readLine()) != null) {
				list.add(tempString);
				line = line + 1;
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return list;
	}

	public String[] splitDrugs(List<String> drugList) {
		Set<String> drugs = new HashSet<String>();
		for (int i = 0; i < drugList.size(); i++) {
			String[] d = getDrugs(drugList.get(i));
			for (int j = 0; j < d.length; j++) {
				drugs.add(d[j]);
			}
		}
		String[] results = new String[drugs.size()];
		int index = 0;
		for (String str : drugs) {
			results[index++] = str;
		}
		return results;
	}

	public String getGengsByDrug(String drug) {
		for (int i = 0; i < all1.size(); i++) {
			if (all1.get(i).startsWith(drug)) {
				return all1.get(i).substring(drug.length() + 1);
			}
		}
		return null;
	}

	public int countAllADR(Map<String, String> drugToMyADR) {
		Set<String> adrs = new HashSet<String>();
		Iterator it = drugToMyADR.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String[] adr = getDrugs(entry.getValue().toString());
			for (String str : adr) {
				adrs.add(str);
			}
		}
		return adrs.size();
	}

	/**
	 * 
	 * @param drugToADRs
	 * @param filteredDrugToADRs
	 * @return 药物,基因数目,原有ADR数目,预测出已知ADR数目,预测出总的ADR数目,正确率
	 */
	public String[][] verify(Map<String, String> drugToADRs) {
		String[][] results = new String[drugToADRs.size()][6];
		for (int i = 0; i < all1.size(); i++) {
			String d_genes = all1.get(i), d_adrs = all2.get(i), adrs = d_adrs
					.substring(d_adrs.indexOf(",") + 1), drug = d_adrs
					.substring(0, d_adrs.indexOf(","));
			results[i][0] = d_genes.substring(0, d_genes.indexOf(","));
			results[i][1] = multiCount(d_genes.substring(
					d_genes.indexOf(",") + 1).split(","))
					+ "";
			results[i][2] = multiCount(adrs.split(",")) + "";
			results[i][3] = getCommonADR(adrs, drugToADRs.get(drug)) + "";
			results[i][4] = multiCount(drugToADRs.get(drug).split(",")) + "";
			results[i][5] = roundDivisionString(Integer.valueOf(results[i][3]),
					Integer.valueOf(results[i][2]), 4);
		}
		return results;
	}

	public int getCommonADR(String target, String source) {
		int count = 0;
		String[] sourceSplit = source.split(",");
		String[] targetSplit = target.split(",");
		for (int i = 0; i < sourceSplit.length; i++) {
			for (int j = 0; j < targetSplit.length; j++) {
				if (sourceSplit[i].equals(targetSplit[j])) {
					count++;
					continue;
				}
			}
		}
		return count;
	}

	public String[][] verify(String[] genes2, Map<String, String>[] results) {
		Map<String, String> drugToMyADR = convertDrugAndADR(results);// 药物到预测副作用的映射
		System.out.println("经过过滤后共检测出" + countAllADR(drugToMyADR) + "种ADRs!");
		Map<String, String> geneToDrug = genesMappingToDrugs(genes2, all1);// 药物到基因的映射
		String[] drugs1 = splitDrugs(new ArrayList<String>(geneToDrug.values()));
		Map<String, String> drugToADR = drugsMappingToADR(drugs1, all2);// 药物的原副作用的映射

		String[][] verifyResults = new String[drugs1.length][5];
		String[] rate = calculateCorrectRate(drugs1, drugToADR, drugToMyADR);
		for (int i = 0; i < drugs1.length; i++) {
			String drug = drugs1[i];
			verifyResults[i][0] = drug;
			verifyResults[i][1] = multiCount(getGengsByDrug(drug).split(","))
					+ "";
			verifyResults[i][2] = multiCount(drugToADR.get(drug).split(","))
					+ "";
			try {
				verifyResults[i][3] = multiCount(drugToMyADR.get(drug).split(
						","))
						+ "";
			} catch (NullPointerException e) {
				verifyResults[i][3] = 0 + "";
			}
			verifyResults[i][4] = rate[i];
		}
		return verifyResults;
	}

	public String[] calculateCorrectRate(String[] drugs,
			Map<String, String> drugToADR, Map<String, String> drugToMyADR) {
		String[] result = new String[drugs.length];
		for (int i = 0; i < drugs.length; i++) {
			int adrs_counts = 0, my_adrs_counts = 0;
			String[] adrs = drugToADR.get(drugs[i]).split(",");
			adrs_counts = multiCount(adrs);
			if (!drugToMyADR.containsKey(drugs[i])) {
				result[i] = 0 + "";
			} else {
				String[] my_adrs = drugToMyADR.get(drugs[i]).split(",");
				for (int j = 0; j < my_adrs.length; j++) {
					if (contain(my_adrs[j], adrs)) {
						my_adrs_counts++;
					}
				}
				result[i] = roundDivisionString(my_adrs_counts, adrs_counts, 4);
			}
		}
		return result;
	}

	public boolean contain(String str, String[] target) {
		for (int i = 0; i < target.length; i++) {
			if (str.equals(target[i])) {
				return true;
			}
		}
		return false;
	}

	public Map<String, String> drugsMappingToADR(String[] drugs,
			List<String> all) {
		Map<String, String> result = new HashMap<String, String>();
		for (String drug : drugs) {
			for (String single : all) {
				if (single.startsWith(drug)) {
					result.put(drug, single.substring(single.indexOf(",") + 1));
				}
			}
		}
		return result;
	}

	public Map<String, String> genesMappingToDrugs(String[] genes,
			List<String> all) {
		Map<String, String> result = new HashMap<String, String>();
		for (String gene : genes) {
			for (String single : all) {
				if (single.indexOf(gene) != -1) {
					if (!result.containsKey(gene)) {
						result.put(gene,
								single.substring(0, single.indexOf(",")));
					} else {
						result.put(
								gene,
								result.get(gene)
										+ ","
										+ single.substring(0,
												single.indexOf(",")));
					}
				}
			}
		}
		return result;
	}

	public Map<String, String> convertDrugAndADR(Map<String, String>[] results) {
		Map<String, String> drugToADR = new HashMap<String, String>();
		for (int i = 0; i < results.length; i++) {
			Iterator it = results[i].entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry entry = (Map.Entry) it.next();
				String[] tmp = entry.getValue().toString().split(",");
				for (int j = 0; j < tmp.length; j++) {
					if (!tmp[j].equals("")) {
						if (drugToADR.containsKey(tmp[j])) {
							String adrs = drugToADR.get(tmp[j]);
							if (adrs.indexOf(entry.getKey() + "") == -1)
								drugToADR.put(tmp[j],
										adrs + "," + entry.getKey());
						} else {
							drugToADR.put(tmp[j], (String) entry.getKey());
						}
					}
				}
			}
		}
		return drugToADR;
	}

	public static String[] getDrugs(String value) {
		List<String> data = new ArrayList<String>();
		for (String str : value.split(",")) {
			if (!isStringBlank(str)) {
				data.add(str);
			}
		}
		String[] results = new String[data.size()];
		for (int i = 0; i < data.size(); i++) {
			results[i] = data.get(i);
		}
		return results;
	}

	public static boolean isAllComma(String str) {
		char[] ch = str.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			if (ch[i] != ',') {
				return false;
			}
		}
		return true;
	}

	public static String filter(String target, String[] words) {
		target = target + ",";
		for (int i = 0; i < words.length; i++) {
			int index = target.indexOf(words[i]);
			while (index != -1) {
				target = target.substring(0, index)
						+ target.substring(target.indexOf(",", index) + 1);
				index = target.indexOf(words[i]);
			}
		}
		if (isAllComma(target)) {
			target = "";
		} else if (target.endsWith(",")) {
			target = target.substring(0, target.length() - 1);
		}
		return target;
	}

	public void export(String title, String fileName, String[][] text) {
		File file = new File("./" + fileName);
		OutputStreamWriter writer = null;
		BufferedWriter bw = null;
		if (file.exists()) {
			file.delete();
		}
		try {
			file.createNewFile();
			OutputStream os = new FileOutputStream(file);
			writer = new OutputStreamWriter(os);
			bw = new BufferedWriter(writer);
			bw.write(title + "\n");
			for (int i = 0; i < text.length; i++) {
				String[] t = text[i];
				StringBuffer sb = new StringBuffer();
				for (int j = 0; j < t.length; j++) {
					sb.append(t[j] + "\t");
				}
				bw.write(sb.toString() + "\n");
			}
			bw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void export(String title, String fileName, List<String[]> text) {
		File file = new File("./" + fileName);
		OutputStreamWriter writer = null;
		BufferedWriter bw = null;
		if (file.exists()) {
			file.delete();
		}
		try {
			file.createNewFile();
			OutputStream os = new FileOutputStream(file);
			writer = new OutputStreamWriter(os);
			bw = new BufferedWriter(writer);
			bw.write(title + "\n");
			for (int i = 0; i < text.size(); i++) {
				String[] t = text.get(i);
				StringBuffer sb = new StringBuffer();
				for (int j = 0; j < t.length; j++) {
					sb.append(t[j] + "\t");
				}
				bw.write(sb.toString() + "\n");
			}
			bw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		ThresholdDetector thresholdDetector = new ThresholdDetector();
		if (args.length == 0) {
			thresholdDetector.dataInput(DGFILENAME, FLAG_D_G);
			thresholdDetector.dataInput(DAFILENAME, FLAG_D_A);
			thresholdDetector.index();
			System.out.println("索引完成，正在写入文件...");
			File f = new File(ThresholdDetector.BADDFILENAME);

			FileOutputStream fos = null;
			ObjectOutputStream oos = null;
			try {
				fos = new FileOutputStream(f);
				oos = new ObjectOutputStream(fos);
				oos.writeObject(thresholdDetector); // 括号内参数为要保存java对象
			} catch (FileNotFoundException e) {
				System.err.println("未找到数据文件!\n" + e);
				f.delete();
				return;
			} catch (IOException e) {
				f.delete();
				System.err.println("数据文件写入出错!\n" + e);
				return;
			} finally {
				try {
					oos.close();
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			System.out.println("数据文件\"gene2ADR.badd\"生成成功！");
		} else if (args.length == 1) {
			FileInputStream fis = null;
			ObjectInputStream ois = null;
			ThresholdDetector object = null;
			File f = new File(BADDFILENAME);
			System.out.println("正在读取数据文件，请稍候...");
			try {
				fis = new FileInputStream(f);
				ois = new ObjectInputStream(new BufferedInputStream(fis));
				object = (ThresholdDetector) ois.readObject();// 强制类型转换
			} catch (FileNotFoundException e) {
				System.err.println("未找到BADD文件!\n" + e);
				return;
			} catch (IOException e) {
				System.err.println("数据文件读取出错!\n" + e);
				return;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				return;
			} finally {
				try {
					ois.close();
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			System.out.println("文件读入成功");
			System.out.println("开始查询所有基因组，请稍候...");

			double threshold = Double.valueOf(args[0]);
			List<String[]> drugsToADRProb = new ArrayList<String[]>();
			Map<String, String> drugToADRs = new HashMap<String, String>();
			List<String> all1 = object.getAll1();
			int count = 0;
			for (int i = 0; i < all1.size(); i++) {
				String gene = all1.get(i);
				String drug = gene.substring(0, gene.indexOf(","));
				String[] genes = getGenes(gene.substring(gene.indexOf(",") + 1));
				Map<String, String>[] results = object.dataHandle(genes);
				String[] multiProb = object.multiGeneResultStatistics(genes,
						results);
				Map<String, String> result = object.getResultData();
				Iterator it = result.entrySet().iterator();
				int index = 0;
				List<String[]> data = new ArrayList<String[]>();
				StringBuffer sb = new StringBuffer();
				while (it.hasNext()) {
					Map.Entry entry = (Map.Entry) it.next();
					// String[] drugs = entry.getValue().toString().split(",");
					sb.append(entry.getKey().toString() + ",");
					drugsToADRProb.add(new String[] { drug,
							entry.getKey().toString(),// 副作用名称
							// multiCount(drugs) + "",// 药物数量
							multiProb[index++] // 概率，保留10位小数
							});
				}
				drugToADRs.put(drug, sb.toString());
				// System.out.println((++count) + ", 药物 " + drug + "对于基因组 "
				// + gene.substring(gene.indexOf(",") + 1) + " 查询完成");
			}
			System.out.println("基因组查询完成");
			object.export("药物名称\tADRs\t概率", "药物概率预测.txt", drugsToADRProb);
			System.out.println("药物概率预测.txt文件生成，显示药物名称,ADRs,概率");
			// for (int i = 0; i < drugsToADRProb.size(); i++) {
			// for (int j = 0; j < drugsToADRProb.get(i).length; j++) {
			// System.out.print(drugsToADRProb.get(i)[j] + "\t");
			// }
			// System.out.println();
			// }
			List<String[]> drugsToADRProb_copy = new ArrayList<String[]>(
					drugsToADRProb);
			Map<String, String> drugToADRs_copy = new HashMap<String, String>(
					drugToADRs);
			String[][] unfilterVerifyResult = object.verify(drugToADRs);

			object.export("药物\t基因数目\t原有ADR数目\t预测出已知ADR数目\t预测出总的ADR数目\t正确率",
					"药物正确率.txt", unfilterVerifyResult);
			System.out
					.println("药物正确率.txt文件生成，显示药物,基因数目,原有ADR数目,预测出已知ADR数目,预测出总的ADR数目,正确率");

			// System.out
			// .println("药物\t基因数目\t原有ADR数目\t预测出已知ADR数目\t预测出总的ADR数目\t正确率");
			// for (int m = 0; m < unfilterVerifyResult.length; m++) {
			// for (int n = 0; n < unfilterVerifyResult[m].length; n++) {
			// System.out.print(unfilterVerifyResult[m][n] + "\t");
			// }
			// System.out.println();
			// }

			System.out.println("当前概率阈值： "
					+ new DecimalFormat("0.00000").format(threshold));
			System.out.println("正在使用阈值过滤...");

			for (int i = 0; i < drugsToADRProb.size(); i++) {
				String[] source = drugsToADRProb.get(i);
				if (Double.valueOf(source[2]) < threshold) {
					drugsToADRProb_copy.remove(drugsToADRProb.get(i));
					String target = drugToADRs_copy.get(source[0]).toString();
					String filtered = filter(target, new String[] { source[1] });
					drugToADRs_copy.put(source[0], filtered);
				}
			}

			System.out.println("过滤完成");
			object.export("药物名称\tADRs\t概率", "药物概率预测_过滤.txt",
					drugsToADRProb_copy);
			System.out.println("药物概率预测_过滤.txt文件生成，显示过滤后药物名称,ADRs,概率");
			// System.out.println("药物名称\tADRs\t概率");
			// for (int i = 0; i < drugsToADRProb_copy.size(); i++) {
			// for (int j = 0; j < drugsToADRProb_copy.get(i).length; j++) {
			// System.out.print(drugsToADRProb_copy.get(i)[j] + "\t");
			// }
			// System.out.println();
			// }
			String[][] verifyResult = object.verify(drugToADRs_copy);
			object.export("药物\t基因数目\t原有ADR数目\t预测出已知ADR数目\t预测出总的ADR数目\t正确率",
					"药物正确率_过滤.txt", verifyResult);
			System.out
					.println("药物正确率_过滤.txt文件生成，显示过滤后药物,基因数目,原有ADR数目,预测出已知ADR数目,预测出总的ADR数目,正确率");
			// System.out
			// .println("药物\t基因数目\t原有ADR数目\t预测出已知ADR数目\t预测出总的ADR数目\t正确率");
			// for (int m = 0; m < verifyResult.length; m++) {
			// for (int n = 0; n < verifyResult[m].length; n++) {
			// System.out.print(verifyResult[m][n] + "\t");
			// }
			// System.out.println();
			// }
		}
	}
}
